﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Collections.Specialized;

using System.Reflection;
using System.Web;
using System.IO;
using Microsoft.VisualBasic;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Serialization;
using Commons;
using System.Data;
using FluorineFx.Json;

namespace lxwmvc
{
    /// <summary>
    /// 功能:系统初始化菜单
    /// [11-03-08 15:39  周二 lxw]<para />
    /// </summary>
    public class applicationhelper
    {
        /// <summary>
        /// 所有的菜单集合
        /// </summary>
        public static Dictionary<string, caidan> CAIDANS = new Dictionary<string, caidan>(StringComparer.OrdinalIgnoreCase);
        /// <summary>
        /// 所有的权限结合
        /// </summary>
        public static Dictionary<string, quanxian> QUANXIANS = new Dictionary<string, quanxian>(StringComparer.OrdinalIgnoreCase);

        /// <summary>
        /// 依赖的ID
        /// </summary>
        public static Dictionary<string, string[]> YILAIS = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
        /// <summary>
        /// 动态页面
        /// </summary>
        public static Dictionary<string, string> syspages = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

        /// <summary>
        /// 城市页面，也属于动态页面
        /// </summary>
        public static Dictionary<string, string> citypage = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);


        internal static Type lxwmvcdll = null;



        /// <summary>
        /// 初始化系统页面
        /// </summary>
        public static void initsyspages()
        {
            //加载外部页面
            try
            {
                var sql = "select bianhao,sysyemianid from sysyemian";
                DataSet ds = sqlhelper.out_getds(sql);
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    //存储到队列中，以后直接读取
                    syspages[dr["bianhao"].tostr()] = dr["syspagesid"].tostr();
                }
            }
            catch { }
        }

        /// <summary>
        /// 初始化系统页面
        /// </summary>
        public static void initcitypages()
        {
            //加载外部页面
            try
            {
                var sql = "select syschengshiid,bianhao from syschengshi";
                DataSet ds = sqlhelper.out_getds(sql);
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    //存储到队列中，以后直接读取
                    citypage[dr["bianhao"].tostr()] = dr["syschengshiid"].tostr();
                }
            }
            catch { }
        }


        /// <summary>
        /// 重新扫描加载菜单和权限
        /// </summary>
        public static void reload()
        {
            var server = HttpContext.Current.Server;

            string strConfig = "lxwmvc.config";
            string strPath = server.MapPath("/");//寻找root目录
            try { Directory.CreateDirectory(Path.Combine(strPath, strConfig)); }
            catch { }

            //初始化系统页面
            initsyspages();

            //初始化系统页面
            initcitypages();


            //先序列化
            string strCaidanPath = "/" + strConfig + "/lxwcaidan.dll";
            string strQuanXianPath = "/" + strConfig + "/lxwquanxian.dll";

            //先每次都能打开
            if (File.Exists(server.MapPath(strCaidanPath)))
                File.Delete(server.MapPath(strCaidanPath));

            if (File.Exists(server.MapPath(strQuanXianPath)))
                File.Delete(server.MapPath(strQuanXianPath));

            CAIDANS.Clear();
            QUANXIANS.Clear();

            initmenupower();
        }

        /// <summary>
        /// 功能:初始化菜单和权限
        /// [11-03-08 15:47  周二 lxw]<para />
        /// </summary>
        public static void initmenupower()
        {
            //判断系统是否允许执行权限操作
            if (!CONIFG.default_quanxian) return;

            //设置程序集
            lxwmvcdll = Assembly.Load("velocity_lxwmvcdll").GetTypes()[0];

            var server = HttpContext.Current.Server;

            string strConfig = "lxwmvc.config";
            string strPath = server.MapPath("/");//寻找root目录
            try { Directory.CreateDirectory(Path.Combine(strPath, strConfig)); }
            catch { }

            //初始化系统页面
            initsyspages();

            //初始化系统页面
            initcitypages();


            //先序列化
            string strCaidanPath = "/" + strConfig + "/lxwcaidan.dll";
            string strQuanXianPath = "/" + strConfig + "/lxwquanxian.dll";

            //先每次都能打开
            if (File.Exists(server.MapPath(strCaidanPath))
                 && File.Exists(server.MapPath(strQuanXianPath))
                 )
            {
                try
                {
                    CAIDANS = readbindll<Dictionary<string,caidan>>(strCaidanPath);
                    QUANXIANS = readbindll<Dictionary<string, quanxian>>(strQuanXianPath);
                }
                catch(Exception err)
                {
                    dataloger.fatal("读取" + strCaidanPath + "出现错误,请设置文件夹everyone可读写。",err);
                }
            }
            else
            {
                //判断重复名称Controller
                //[11-03-10 10:42 lxw]
                var types = lxwmvcdll.Assembly.GetTypes();

                foreach (var type in types)
                {
                    Type classType = type;
                    string strBaseAssemblyName = classType.FullName.ToLower();
                    if (!strBaseAssemblyName.EndsWith("controller", StringComparison.OrdinalIgnoreCase)) 
                        continue;

                    MethodInfo[] methods = classType.GetMethods(
                        BindingFlags.Public | 
                        BindingFlags.Instance | 
                        BindingFlags.Static | 
                        BindingFlags.DeclaredOnly);

                    foreach (MethodInfo method in methods)
                    {
                        object[] attributesmenu = method.GetCustomAttributes(typeof(caidanAttribute), true);
                        object[] attributespower = method.GetCustomAttributes(typeof(quanxianAttribute), true);
                        object[] attributesdepend = method.GetCustomAttributes(typeof(yilaiAttribute), true);

                        //生成菜单的一些基本信息
                        string strcontroller = classType.Name.ToLower();
                        strcontroller = strcontroller.Replace("controller", "");

                        if (attributesmenu != null && attributesmenu.Length == 1)
                        {
                            caidanAttribute _atmenu = attributesmenu[0] as caidanAttribute;
                            if (string.IsNullOrEmpty(_atmenu.mingcheng) && _atmenu.mingcheng.Trim() == "")
                                throw new Exception(
                                    "菜单没有设置菜单名称：" + "@" + strcontroller + "@" + method.Name
                                    );

                            caidan syscaidan = new caidan();
                            //菜单编号
                            syscaidan.biaoshi = "@" + strcontroller + "@" + method.Name;
                            syscaidan.path = "/" + strcontroller + "/" + method.Name + "";
                            syscaidan.mingcheng = _atmenu.mingcheng;

                            //不可能再出现重复
                            //[11-03-10 13:15 lxw]
                            if (CAIDANS.ContainsKey(syscaidan.biaoshi))
                                throw new Exception(
                                    string.Format("存在相同的菜单ID:{0},两个名称是:{1}/{2}",
                                    syscaidan.biaoshi,
                                    CAIDANS[syscaidan.biaoshi].mingcheng,
                                    syscaidan.mingcheng
                                    ));




                            CAIDANS[syscaidan.biaoshi] = syscaidan;
                        }

                        if (attributespower != null && attributespower.Length == 1)
                        {
                            quanxianAttribute _atpower = attributespower[0] as quanxianAttribute;
                            if (string.IsNullOrEmpty(_atpower.mingcheng) && _atpower.mingcheng.Trim() == "")
                                throw new Exception(
                                    "权限没有设置权限名称：" + "@" + strcontroller + "@" + method.Name
                                    );

                            if(string.IsNullOrEmpty(_atpower.caidan) && _atpower.caidan.Trim() == "")
                                throw new Exception(
                                    "权限没有设置菜单信息："+"@" + strcontroller + "@" + method.Name
                                    );

                            quanxian sysquanxian = new quanxian();
                            //权限编号
                            sysquanxian.biaoshi = "@" + strcontroller + "@" + method.Name;
                            sysquanxian.mingcheng = _atpower.mingcheng;

                            var caidans = _atpower.caidan.Split(new char[]{'.','/','\\','-',':','_','?','!'});
                            if(caidans.Length == 2)
                                sysquanxian.caidan = "@" + caidans[0] + "@" + caidans[1];
                            else
                                sysquanxian.caidan = "@" + strcontroller + "@" + caidans[0];

                            //不可能再出现重复
                            //[11-03-10 13:15 lxw]
                            if (QUANXIANS.ContainsKey(sysquanxian.biaoshi))
                                throw new Exception(
                                    string.Format("存在相同的权限ID:{0},两个名称是:{1}/{2}",
                                    sysquanxian.biaoshi,
                                    QUANXIANS[sysquanxian.biaoshi].mingcheng,
                                    sysquanxian.mingcheng
                                    ));


                            QUANXIANS[sysquanxian.biaoshi] = sysquanxian;
                        }

                        if (attributesdepend != null && attributesdepend.Length == 1)
                        {
                            yilaiAttribute _atdepend = attributesdepend[0] as yilaiAttribute;
                            if (string.IsNullOrEmpty(_atdepend.quanxian_caidan) && _atdepend.quanxian_caidan.Trim() == "")
                                throw new Exception(
                                    "权限没有设置菜单信息：" + "@" + strcontroller + "@" + method.Name
                                    );
                        }
                    }
                }

                //遍历views
                DirectoryInfo di = new DirectoryInfo(strPath + "/views");
                foreach (var d in di.GetDirectories())
                {
                    string dname = d.Name.ToLower();
                    //布局的排除在外
                    if (dname == "layout" || dname == "customerrors") continue;

                    FileInfo[] fis = d.GetFiles("*.htm");
                    List<string[]> lst = new List<string[]>();
                    foreach (var f in fis)
                    {
                        string fname = Path.GetFileNameWithoutExtension(f.FullName);
                        string menuname = ("@" + dname + "@" + fname).ToLower();
                        string powername = ("@" + dname + "@" + fname).ToLower();
                        //证明已经存在action里面的内容了
                        if (CAIDANS.ContainsKey(menuname) || QUANXIANS.ContainsKey(powername)) continue;

                        string header = "";
                        using (StreamReader sr = new StreamReader(f.FullName, Encoding.Default))
                        {
                            header = sr.ReadLine();
                        }
                        header = header.Replace(" ", "");
                        //存在才执行
                        while (true && header != "")
                        {
                            if (header.IndexOf("##[caidan(\"") != -1)
                            {
                                string name = header.Substring(11, header.LastIndexOf("\"") - 11);
                                lst.Add(new string[] { "caidan", dname, fname, name, "" });
                                break;
                            }
                            if (header.IndexOf("##[quanxian(\"") != -1)
                            {
                                string name = header.Substring(13, header.LastIndexOf("\"") - 13);
                                name = name.Replace(" ", "");
                                lst.Add(new string[] { "quanxian", dname, fname, Regex.Split(name, "\",\"")[0], Regex.Split(name, "\",\"")[1] });
                                break;
                            }
                            if (header.IndexOf("##[yilai(\"") != -1)
                            {
                                string name = header.Substring(9, header.LastIndexOf("\")") - 9);          
                                lst.Add(new string[] { "yilai", dname, fname, name, "" });
                                break;
                            }
                            break;
                        }
                    }


                    //============================================>
                    //循环
                    foreach (var l in lst)
                    {
                        string path = l[1] + "/" + l[2];
                        //访问这个view的时候，需要检查权限
                        YILAIS[path] = l;

                        if (l[0] == "caidan")
                        {

                            caidan caidan = new caidan();
                            //菜单编号
                            caidan.biaoshi = "@" + l[1] + "@" + l[2];
                            caidan.mingcheng = l[3];
                            //这个设置比较变态
                            caidan.path = "/table/" + l[1] + "/" + l[2] + "";
                            //不可能再出现重复
                            //[11-03-10 13:15 lxw]
                            if (CAIDANS.ContainsKey(caidan.biaoshi))
                                throw new Exception(
                                    string.Format("存在相同的菜单ID:{0},两个名称是:{1}/{2}",
                                    caidan.biaoshi,
                                    CAIDANS[caidan.biaoshi].mingcheng,
                                    caidan.mingcheng
                                    ));
                            CAIDANS[caidan.biaoshi] = caidan;
                            continue;
                        }
                        if (l[0] == "quanxian")
                        {
                            quanxian quanxian = new quanxian();
                            //权限编号
                            quanxian.biaoshi = "@" + l[1] + "@" + l[2];
                            quanxian.caidan = l[4];
                            quanxian.mingcheng = l[3];

                            //不可能再出现重复
                            //[11-03-10 13:15 lxw]
                            if (QUANXIANS.ContainsKey(quanxian.biaoshi.ToLower()))
                                throw new Exception(
                                    string.Format("存在相同的权限ID:{0},两个名称是:{1}/{2}",
                                    quanxian.biaoshi,
                                    QUANXIANS[quanxian.biaoshi].mingcheng,
                                    quanxian.mingcheng
                                    ));


                            QUANXIANS[quanxian.biaoshi] = quanxian;
                            continue;
                        }
                        if (l[0] == "yilai")
                        {
                            //string path = l[1].ToUpper() + "/" + l[2].ToUpper();
                            //hasViewYiLai[path] = l[3];
                        }
                    }

                }

                createbindll(strCaidanPath, CAIDANS);
                createbindll(strQuanXianPath, QUANXIANS);
            }

            try
            {
                //进入菜单以后再操作


                //TODO:2013.03.01
                //string sql = "select * from syscaidan where leixing='0' ";
                //DataTable dtmenu = sqlhelper.out_getds(sql).Tables[0];//系统数据库已存在的所有系统菜单

                //string menus = "";

                //sql = "insert into syscaidan(path,biaoshi,title,sfxianshi,leixing,shangji,jibie,paixu) values('{0}','{1}','{2}','{3}','{4}','{5}','{6}',{7})";
                //foreach (caidanAttribute menu in applicationhelper.hasMenu.Values)
                //{
                //    menus += menus == "" ? "'" + menu.biaoshi + "'" : ",'" + menu.biaoshi + "'";
                //    if (dtmenu.Select(" menuname='" + menu.biaoshi + "'").Length == 0)//系统中不存在  则插入
                //    {
                //        Hashtable has = new Hashtable();
                //        has["menuname"] = menu.biaoshi;
                //        has["actionpath"] = menu.path;
                //        has["title"] = menu.mingcheng;
                //        has["paixu"] = 0;//排序默认为0
                //        has["leixing"] = "0";//系统菜单
                //        has["jibie"] = 1;
                //        has["shangji"] = "";
                //        has["sfxianshi"] = "1";

                //        sqlhelper.out_exec(string.Format(sql,//插入
                //            has["menuname"],
                //            has["actionpath"],
                //            has["title"],
                //            has["sfxianshi"],
                //            has["leixing"],
                //            has["shangji"],
                //            has["jibie"],
                //            has["paixu"]));
                //    }
                //}

                ////删除 被删除的菜单
                //sql = "delete from caidan where leixing='0' and menuname not in(" + menus + ") ";
                //sqlhelper.out_exec(sql);
            }
            catch
            {

            }
        }

        readonly static object[] syn = new object[0] { };
        /// <summary>
        /// 功能:把has表生成缓存文件
        /// [11-03-08 15:47  周二 lxw]<para />
        /// </summary>
        /// <param name="strPathName">路径</param>
        /// <param name="has">哈希表</param>
        static void createbindll<T>(string strPathName, T has)
        {
            lock (syn)
            {
                string str = JavaScriptConvert.SerializeObject(has);
                var filePath = HttpContext.Current.Server.MapPath(strPathName);

                if (File.Exists(filePath)) File.Delete(filePath);
                //序列化存储到BIN目录。
                using (StreamWriter sw = new StreamWriter(filePath))
                {
                    sw.Write(str);
                }
            }
        }

        /// <summary>
        /// 功能:从文件中读取出来到哈希表
        /// [11-03-08 15:48  周二 lxw]<para />
        /// </summary>
        /// <param name="strPathName">文件路径</param>
        static T readbindll<T>(string strPathName)
        {
            lock (syn)
            {
                var filePath = HttpContext.Current.Server.MapPath(strPathName);
                string source = "";
                using (StreamReader sr = new StreamReader(filePath))
                {
                    source = sr.ReadToEnd();
                }

                return JavaScriptConvert.DeserializeObject<T>(source);
            }
        }

        /// <summary>
        /// 创建实体类和描述
        /// </summary>
        /// <param name="conn"></param>
        public static void CreateModels(string conn)
        {
            string sql = @"
SELECT
    TableName=CASE WHEN C.column_id=1 THEN O.name ELSE N'' END,
    TableDesc=ISNULL(CASE WHEN C.column_id=1 THEN PTB.[value] END,N''),
    Column_id=C.column_id,
    ColumnName=C.name,
    PrimaryKey=ISNULL(IDX.PrimaryKey,N''),
    [IDENTITY]=CASE WHEN C.is_identity=1 THEN N'√'ELSE N'' END,
    Computed=CASE WHEN C.is_computed=1 THEN N'√'ELSE N'' END,
    Type=T.name,
    Length=C.max_length,
    Precision=C.precision,
    Scale=C.scale,
    NullAble=CASE WHEN C.is_nullable=1 THEN N'√'ELSE N'' END,
    [Default]=ISNULL(D.definition,N''),
    ColumnDesc=ISNULL(PFD.[value],N''),
    IndexName=ISNULL(IDX.IndexName,N''),
    IndexSort=ISNULL(IDX.Sort,N''),
    Create_Date=O.Create_Date,
    Modify_Date=O.Modify_date
FROM sys.columns C
    INNER JOIN sys.objects O
        ON C.[object_id]=O.[object_id]
            AND O.type='U'
            AND O.is_ms_shipped=0
    INNER JOIN sys.types T
        ON C.user_type_id=T.user_type_id
    LEFT JOIN sys.default_constraints D
        ON C.[object_id]=D.parent_object_id
            AND C.column_id=D.parent_column_id
            AND C.default_object_id=D.[object_id]
    LEFT JOIN sys.extended_properties PFD
        ON PFD.class=1
            AND C.[object_id]=PFD.major_id
            AND C.column_id=PFD.minor_id
--             AND PFD.name='Caption'  -- 字段说明对应的描述名称(一个字段可以添加多个不同name的描述)
    LEFT JOIN sys.extended_properties PTB
        ON PTB.class=1
            AND PTB.minor_id=0
            AND C.[object_id]=PTB.major_id
--             AND PFD.name='Caption'  -- 表说明对应的描述名称(一个表可以添加多个不同name的描述)
    LEFT JOIN                       -- 索引及主键信息
    (
        SELECT
            IDXC.[object_id],
            IDXC.column_id,
            Sort=CASE INDEXKEY_PROPERTY(IDXC.[object_id],IDXC.index_id,IDXC.index_column_id,'IsDescending')
                WHEN 1 THEN 'DESC' WHEN 0 THEN 'ASC' ELSE '' END,
            PrimaryKey=CASE WHEN IDX.is_primary_key=1 THEN N'√'ELSE N'' END,
            IndexName=IDX.Name
        FROM sys.indexes IDX
        INNER JOIN sys.index_columns IDXC
            ON IDX.[object_id]=IDXC.[object_id]
                AND IDX.index_id=IDXC.index_id
        LEFT JOIN sys.key_constraints KC
            ON IDX.[object_id]=KC.[parent_object_id]
                AND IDX.index_id=KC.unique_index_id
        INNER JOIN  -- 对于一个列包含多个索引的情况,只显示第1个索引信息
        (
            SELECT [object_id], Column_id, index_id=MIN(index_id)
            FROM sys.index_columns
            GROUP BY [object_id], Column_id
        ) IDXCUQ
            ON IDXC.[object_id]=IDXCUQ.[object_id]
                AND IDXC.Column_id=IDXCUQ.Column_id
                AND IDXC.index_id=IDXCUQ.index_id
    ) IDX
        ON C.[object_id]=IDX.[object_id]
            AND C.column_id=IDX.column_id
            
            
           ";



            DataTable dt = sqlhelper.out_getds(sql, conn).Tables[0];
            string tablename = "";
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i]["tablename"].tostr().Length > 0)
                {
                    tablename = dt.Rows[i]["tablename"].tostr();
                }
                else
                {
                    //赋值，把没有信息的补全
                    dt.Rows[i]["tablename"] = tablename;
                }
            }

            StringBuilder sb = new StringBuilder();

            string t = @"
// ===============================================================================
// 实体类及实体描述自动生成，建议不要修改，如果数据库有变更，请重新生成即可
// 最后的生成时间:{0}
// ==============================================================================";

            sb.AppendFormat(t, DateTime.Now);

            sb.Append(@"
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Text;
using System.IO;
using System.Dynamic;");

            sb.AppendLine("");
            sb.AppendLine("");
            sb.AppendLine("namespace lxwmvc");
            sb.AppendLine("{");

            var tbs = dt.Select("tablename<>''");

            //columnname,primarykey,inentity,type,length,precision,scale,NullAble,default,columnDesc,create_date,modify_date
            List<string> list = new List<string>();

            foreach (DataRow dr in tbs)
            {
                if (list.Contains(dr["tablename"] + "")) continue;
                list.Add(dr["tablename"] + "");
                sb.AppendLine("     /// <summary>");
                sb.AppendLine("     /// " + dr["tablename"]);
                sb.AppendLine("     /// </summary>");
                sb.AppendLine("     public class _" + dr["tablename"] + "_");
                sb.AppendLine("     {");
                sb.AppendLine("          /// <summary>表名</summary>");
                sb.AppendLine("          public static string TABLE_NAME = \"" + dr["tablename"] + "\";");
                var rs = dt.Select("tablename='" + dr["tablename"] + "'");
                foreach (DataRow dr2 in rs)
                {
                    string c = dr2["columnname"].tostr();
                    if (c.IndexOf('=') != -1) continue;
                    sb.AppendLine("         /// <summary>");
                    sb.AppendLine("         /// 描述=>" + dr2["columnDesc"].tostr().Replace("\n", "").Replace("\r", "") + "");
                    sb.AppendLine("         /// <para>primarykey=" + dr2["primarykey"] + "</para>");
                    sb.AppendLine("         /// <para>IDENTITY=" + dr2["IDENTITY"] + "</para>");
                    sb.AppendLine("         /// <para>type=" + dr2["type"] + "</para>");
                    sb.AppendLine("         /// <para>length=" + dr2["length"] + "</para>");
                    sb.AppendLine("         /// <para>NullAble=" + dr2["NullAble"] + "</para>");
                    sb.AppendLine("         /// <para>default=" + dr2["default"] + "</para>");
                    sb.AppendLine("         /// <para>precision=" + dr2["precision"] + "</para>");
                    sb.AppendLine("         /// <para>scale=" + dr2["scale"] + "</para>");
                    sb.AppendLine("         /// <para>modify_date=" + dr["modify_date"] + "</para>");


                    sb.AppendLine("         /// <para>create_date=" + dr2["create_date"] + "</para>");
                    sb.AppendLine("         /// </summary>");
                    sb.AppendLine("         public static string " + dr2["columnname"] + " = \"" + dr2["columnname"] + "\";");
                }

                sb.AppendLine("     }");
            }


            list.Clear();
            foreach (DataRow dr in tbs)
            {
                if (list.Contains(dr["tablename"] + "")) continue;
                list.Add(dr["tablename"] + "");
                sb.AppendLine("     /// <summary>");
                sb.AppendLine("     /// " + dr["tablename"]);
                sb.AppendLine("     /// </summary>");
                sb.AppendLine("     public class _" + dr["tablename"] + ":supermodel");
                sb.AppendLine("     {");

                sb.AppendLine("         /// <summary>");
                sb.AppendLine("         /// " + dr["tablename"]);
                sb.AppendLine("         /// </summary>");
                sb.AppendLine("         public _" + dr["tablename"] + "():base(_" + dr["tablename"] + "_.TABLE_NAME){}");
                var rs = dt.Select("tablename='" + dr["tablename"] + "'");
                foreach (DataRow dr2 in rs)
                {
                    string c = dr2["columnname"].tostr();
                    if (c.IndexOf('=') != -1) continue;
                    sb.AppendLine("         /// <summary>");
                    sb.AppendLine("         /// =>字段信息：" + dr2["columnDesc"].tostr().Replace("\n", "").Replace("\r", "") + "");
                    sb.AppendLine("         /// <para>primarykey=" + dr2["primarykey"] + "</para>");
                    sb.AppendLine("         /// <para>IDENTITY=" + dr2["IDENTITY"] + "</para>");
                    sb.AppendLine("         /// <para>type=" + dr2["type"] + "</para>");
                    sb.AppendLine("         /// <para>length=" + dr2["length"] + "</para>");
                    sb.AppendLine("         /// <para>NullAble=" + dr2["NullAble"] + "</para>");
                    sb.AppendLine("         /// <para>default=" + dr2["default"] + "</para>");
                    sb.AppendLine("         /// <para>precision=" + dr2["precision"] + "</para>");
                    sb.AppendLine("         /// <para>scale=" + dr2["scale"] + "</para>");
                    sb.AppendLine("         /// <para>modify_date=" + dr["modify_date"] + "</para>");


                    sb.AppendLine("         /// <para>create_date=" + dr2["create_date"] + "</para>");
                    sb.AppendLine("         /// </summary>");
                    sb.AppendLine("         public " + gettype(dr2["type"]) + " " + dr2["columnname"] + "{");
                    sb.AppendLine("             get{return this.get<" + gettype(dr2["type"]) + ">(_" + dr["tablename"] + "_." + dr2["columnname"] + ");}");
                    sb.AppendLine("             set{this[_" + dr["tablename"] + "_." + dr2["columnname"] + "]=value;}");
                    sb.AppendLine("         }");
                }

                sb.AppendLine("     }");
            }
            sb.AppendLine("}");

            //int resultCode = 0;
            //以字符流的形式下载文件
            byte[] bytes = Encoding.Default.GetBytes(sb.tostr());
            HttpContext.Current.Response.ContentType = "application/octet-stream";
            //通知浏览器下载文件而不是打开
            HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;  filename=" + HttpUtility.UrlEncode("sys_models.cs", System.Text.Encoding.UTF8));
            HttpContext.Current.Response.BinaryWrite(bytes);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }

        private static string gettype(object p)
        {
            string p0 = p.tostr();
            if (p0 == "int") return "int?";
            if (p0 == "long") return "long?";
            if (p0 == "decimal") return "decimal?";
            if (p0 == "datetime") return "DateTime?";
            return "string";
        }
    }
}